/*
 * COMP6471 Project6
 * 
 * Assignment 6: Due 23:59 Sunday 4 December 2011. 
 * Submit a .tar.gz file with your Java program, and a 4-page description of your architecture to 
 * Project 6 of electronic submission system. 
 * Third version of an interactive game in Java for Kenken. It supports a good game: a user can 
 * select a game, enter values into grid locations, the user can track possible entries into grid 
 * locations, and the systems reports success or failure when the grid is full. The user can request 
 * hints. 
 * The game is selected from a list of games that you provide for the system.
 * 
 * This file is created by Yuan Tao (ewan.msn@gmail.com)
 * Licensed under GNU GPL v3
 * 
 * $Author: ewan.msn@gmail.com $
 * $Date: 2011-12-03 21:16:31 +0000 (Sat, 03 Dec 2011) $
 * $Rev: 68 $
 * $HeadURL: http://comp6471.googlecode.com/svn/Project6/src/Project6Main.java $
 * 
 */

import java.text.SimpleDateFormat;
import java.util.ArrayList;


import kklib.*;
import ui.UIConsole;
import utils.*;

public class Project6Main {
	
	public static ArrayList<Layout> layouts = new ArrayList<Layout>();

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// create and initialize the logger
		SysLogger.init();		// NOTE: apply Singleton pattern?

		// create a Console UI instance
		UIConsole ui = new UIConsole();
		
		// add UIConsole to observer list
		UIControllerFacade.getInstance().addObserver(ui);
		
		// show greetings
		if (ui.showGreetings() != 0) {
			ui.showMessage("showGreetings error.");
			return;
		}

		// format the result.txt file.
		SimpleDateFormat tmpDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String datetimeNow = tmpDate.format(new java.util.Date());
		SysLogger.output(datetimeNow + "\nThe result is:" + "\n");
		
		// load all txt files
		GameLoader txtLoader = new GameLoader();
		String path = System.getProperty("user.dir") + "\\input";
		if (txtLoader.loadTextFiles(path, layouts) != 0) {
			return;
		}

		// checking
		Layout layout = null;
		for (int i = 0; i < layouts.size(); i++) {
			layout = layouts.get(i);

			// logging
			SysLogger.info(layout.fileFullname);
			SysLogger.info(layout.txtFileData.toString());

			// parse one file
			if (txtLoader.fileDataParser(layout) != 0) {
				ui.showMessage("fileDataParser error, please see logs for more information.");
				return;		// exit
			}
			// check the syntax of the cages and cells.
			if (layout.syntaxChecker() != 0) {
				ui.showMessage("syntaxChecker error, please see logs for more information.");
				return;
			}
			
			// add data to cells for printing
			layout.addDataToCells();
			
			// set right values
			if (layout.setRightValues() != 0) {
				ui.showMessage("Fail to find a solution, please see logs for more information.");
				return;
			}
		}
		
		boolean ifExit = false;
		int gameNo = -1;
		
		while (!ifExit) {
			// show all games
			gameNo = ui.showAllGamesAndChooseAGame(layouts);
			if (gameNo == -1) {
				break;				// exit command
			}
			
			// handle the UI request to choosing a game
			if (UIControllerFacade.getInstance().chooseAGame(layouts, gameNo) != 0) {
				ui.showMessage("Fail to select a game, please try again.");
			}
			
			// get cell value(s) and check if they are right
			while (true) {
				// get values or possible values for cells
				String values = ui.getCommands();
				String strCmd = values.charAt(0) + "";
				int ret = 0, cmd = 0;
				
				try {
					cmd = Integer.parseInt(strCmd);
				} catch (NumberFormatException e) {
					cmd = 0;
				}

				if (values == null || cmd == 0) {
					ifExit = true;
					ui.showMessage("FATAL error while getting commands.");					
					break;
				}
				
				// handle UI commands
				values = values.substring(1);
				if (cmd == UIConsole.EXIT) {
					ifExit = true;
					break;
					
				} else if (cmd == UIConsole.SETPV) {
					// handle the UI request to set possible values for cells
					ret = UIControllerFacade.getInstance().setPossibleValuesForCells(values);
					if (ret == 0) {
						ret = 1;
					}
					
				} else if (cmd == UIConsole.SETV) {
					// handle the UI request to set values for cells
					ret = UIControllerFacade.getInstance().setValuesForCells(values);
					
				} else {
					// handle the UI request to get hints
					ret = UIControllerFacade.getInstance().getHint(values);
				}
				
				// check the result
				if (ret == 0) {
					ui.showMessage("Congratulations!");
					break;

				} else if (ret == 1) {
					// need to set values for more cells.
					continue;
					

				} else if (ret == 2) {
					String msg = "Input error (make sure the name and value of cell are meaningful ";
					msg += "and do not use BACKSPACE or DELETE key), please try it again";
					ui.showMessage(msg);
					continue;
					
				} else if (ret == 3) {
					ifExit = true;		// FATAL error.
					ui.showMessage("FATAL error while setting values to cells.");
					break;

				} else {
					ui.showMessage("Sorry, please check the values of the cells.");
				}
				
			}
			
			if (!ifExit && !ui.ifPlayAgain()) {
				break;
			}
		}

		ui.showMessage("The program ends.");
	}

}
